package com.platform.modules.cpt.service.impl;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.activiti.engine.delegate.DelegateExecution;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import org.springframework.web.util.WebUtils;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.util.StringUtil;
import com.platform.common.exception.BusinessException;
import com.platform.common.utils.DownloadUtils;
import com.platform.common.utils.MapUtil;
import com.platform.common.utils.Query;
import com.platform.common.utils.UUID;
import com.platform.dao.AttachmentDao;
import com.platform.entity.Attachment;
import com.platform.modules.act.ctx.entity.ProcessObject;
import com.platform.modules.act.ctx.service.ProcessObjectService;
import com.platform.modules.cpt.dao.CptAcceptanceDao;
import com.platform.modules.cpt.entity.CptAcceptanceEntity;
import com.platform.modules.cpt.entity.CptAcceptanceTeamEntity;
import com.platform.modules.cpt.service.CptAcceptanceService;
import com.platform.modules.cpt.service.CptAcceptanceTeamService;
import com.platform.modules.prj.entity.PrjProjectEntity;
import com.platform.modules.prj.service.PrjProjectService;
import com.platform.modules.sys.entity.SysOrgEntity;
import com.platform.modules.sys.service.SysOrgService;
import com.platform.util.DocUtil;

@Service("cptAcceptanceService")
public class CptAcceptanceServiceImpl extends ServiceImpl<CptAcceptanceDao, CptAcceptanceEntity> implements CptAcceptanceService {

    private static final Logger logger = LoggerFactory.getLogger(CptAcceptanceServiceImpl.class);
    
    @Autowired
    AttachmentDao attachmentDao;

	@Autowired
	private ProcessObjectService processObjectService;

	@Autowired
	private CptAcceptanceTeamService cptAcceptanceTeamService;

    @Autowired
    private PrjProjectService projectService;
    @Autowired
    SysOrgService sysOrgService;
	
    @Autowired
    private DocUtil docUtil;

//    @Override
//    public boolean save(CptAcceptanceEntity entity) {
//        if(StringUtils.isBlank(entity.getId())) {
//            this.baseMapper.insert(entity);
//        }else {
//            this.baseMapper.updateById(entity);
//        }
//        return true;
//    }

    @Override
    public Page<CptAcceptanceEntity> queryPage(Map<String, Object> params) {
        params.put("sidx", "T.CREATE_TIME");
        params.put("asc", false);
        Page<CptAcceptanceEntity> page = new Query<CptAcceptanceEntity>(params).getPage();
        List<CptAcceptanceEntity> list = baseMapper.selectList(page, params);
        return page.setRecords(list);
    }

    @Override
    public CptAcceptanceEntity queryOne(Map<String, Object> params) {
        params.put("sidx", "T.CREATE_TIME");
        params.put("asc", false);
        List<CptAcceptanceEntity> list = baseMapper.selectList(null, params);
        if(list==null || list.isEmpty()){
            return null;
        }else if(list.size()==1){
            return list.get(0);
        }else {
            return list.get(0);
        }
    }

    @Override
    public List<CptAcceptanceEntity> queryList(Map<String, Object> params) {
        return baseMapper.selectList(null, params);
    }

	@Override
	public void updateStatus(DelegateExecution execution) {
		
		String poId = (String) execution.getVariable("poId");
		//END endevent2
		String endevent2 = (String) execution.getVariable("endevent2");
		//监管 - 竣工验收监督
		String jgysjd = (String) execution.getVariable("jgysjd");
		//建设 - 编写竣工验收情况
		String bxjgysqk = (String) execution.getVariable("bxjgysqk");
		//质监站 - 编写竣工验收监督报告
		String bxjgysjdbg = (String) execution.getVariable("bxjgysjdbg");
		//监管 - 盖章
		String jggz = (String) execution.getVariable("jggz");
		//建设-组织编写竣工验收报告
		String bxjgysbg = (String) execution.getVariable("bxjgysbg");
		//完成
		String endevent1 = (String) execution.getVariable("endevent1");
		
		
		
		ProcessObject processObject = processObjectService.getById(poId);
		if(null==processObject) {
			logger.error("未找到工作流业务对象poId:{}",poId);
			return ;
		}
		
		CptAcceptanceEntity cptAcceptanceEntity = baseMapper.selectById(processObject.getBusinessId());
		if(null==cptAcceptanceEntity) {
			logger.error("未找到工作流业务对象businessId:{}",processObject.getBusinessId());
			return ;
		}
		
		
		//监督申请被拒绝
		if("".equals(endevent2)) {
			 //10-条件核查不符 11-竣工验收监督不符合
			if(1==cptAcceptanceEntity.getStatus()) {
				cptAcceptanceEntity.setStatus(10);
			}else {
				cptAcceptanceEntity.setStatus(11);
			}
		}else if("".equals(endevent1)){
			 //7-完成
			cptAcceptanceEntity.setStatus(7);
		}else if(StringUtil.isNotEmpty(bxjgysbg) && !"false".equals(bxjgysbg)){
			 //6-组织编写竣工验收报告
			cptAcceptanceEntity.setStatus(6);
		}else if(StringUtil.isNotEmpty(jggz) && !"false".equals(jggz)){
			 //5-监管盖章
			cptAcceptanceEntity.setStatus(5);
		}else if(StringUtil.isNotEmpty(bxjgysjdbg) && !"false".equals(bxjgysjdbg)){
			 //4-编写竣工验收监督报告
			cptAcceptanceEntity.setStatus(4);
		}else if(StringUtil.isNotEmpty(bxjgysqk) && !"false".equals(bxjgysqk)){
			 //3-填写验收结论
			cptAcceptanceEntity.setStatus(3);
		}else if(StringUtil.isNotEmpty(jgysjd) && !"false".equals(jgysjd)){
			 //2-验收监督中
			cptAcceptanceEntity.setStatus(2);
		}else {
			logger.error("updateStatus error, poId: {}", poId);
		}
		
		cptAcceptanceEntity.setUpdateTime(new Date());
		baseMapper.updateById(cptAcceptanceEntity);
	}

	@Override
	public void start(DelegateExecution execution) {
		String poId = (String) execution.getVariable("poId");
		System.out.println("poId:"+execution.getVariable("poId"));
		ProcessObject processObject = processObjectService.getById(poId);
		if(null==processObject) {
			logger.error("未找到工作流业务对象poId:{}",poId);
			return ;
		}
		
		CptAcceptanceEntity cptAcceptanceEntity = baseMapper.selectById(processObject.getBusinessId());
		if(null==cptAcceptanceEntity) {
			logger.error("未找到工作流业务对象businessId:{}",processObject.getBusinessId());
			return ;
		}
		
		//1-监督条件审批中
		cptAcceptanceEntity.setStatus(1);
		cptAcceptanceEntity.setUpdateTime(new Date());
		baseMapper.updateById(cptAcceptanceEntity);
	}

	@Override
	public Map<String, Object> createGcjgysjdtzsFile(CptAcceptanceEntity cptAcceptanceEntity) {
		Map<String, Object> result = new HashMap<>();

		CptAcceptanceEntity cptAcceptance = baseMapper.selectById(cptAcceptanceEntity.getId());
		if(null==cptAcceptance) {
			throw new BusinessException("未找到竣工验收记录");
		}

		//删除通知书历史文件
		List<Attachment> attList = docUtil.getAttListByAttBusinessIdAndAttCode(cptAcceptanceEntity.getId(),"CPT_ACCPTANCE_FILES_GCJGYSJDTZS");
		if(null!=attList && attList.size()>0) {
			for(int i=0; i<attList.size(); i++) {
				Attachment attachment = attList.get(i);
				docUtil.deleteAtts(Arrays.asList(attachment.getId().split(",")));
			}
		}
		
		Map<String,Object> params = new HashMap<String,Object>();
		params.put("cptId", cptAcceptanceEntity.getId());
		List<CptAcceptanceTeamEntity> teamList = cptAcceptanceTeamService.queryList(params);
		

    	PrjProjectEntity project = projectService.getById(cptAcceptance.getPrjId());
    	String conutyNum = project.getCountyNum();
    	SysOrgEntity org = sysOrgService.getOne(new QueryWrapper<SysOrgEntity>().allEq(MapUtil.of("ORG_LEVEL","4","COUNTY_NO",conutyNum)));
    	if(null==org) {
			throw new BusinessException("未找到质监站");
    	}
        
        Calendar cal=Calendar.getInstance();
        cal.setTime(cptAcceptance.getAptDate());
        int year = cal.get(Calendar.YEAR);//获取年份
        int month=cal.get(Calendar.MONTH);//获取月份
        int day=cal.get(Calendar.DATE);//获取日
        int hour=cal.get(Calendar.HOUR);//小时
        int minute=cal.get(Calendar.MINUTE);//分           
        int second=cal.get(Calendar.SECOND);//秒 
        
        Calendar cal2=Calendar.getInstance();  
        int year2=cal2.get(Calendar.YEAR);//获取年份
        int month2=cal2.get(Calendar.MONTH);//获取月份
        int day2=cal2.get(Calendar.DATE);//获取日
		
        //组装参数
		Map<String, Object> data = new HashMap<String, Object>();
		data.put("ag1", org.getOrgName());
		data.put("ag2", cptAcceptance.getBuildCorpName());
		data.put("ag3", ""+year);
		data.put("ag4", ""+(month+1));
		data.put("ag5", ""+day);
		data.put("ag6", ""+hour);
		data.put("ag7", cptAcceptance.getSite());
		data.put("ag8", cptAcceptance.getLeader());
		data.put("ag9", cptAcceptance.getMembers());
		data.put("ag10", cptAcceptance.getDeputyLeader());
		data.put("ag11", teamList);
		data.put("ag12", ""+year2);
		data.put("ag13", ""+(month2+1));
		data.put("ag14", ""+day2);
		//替换null值
		processMap(data);
		
		//导出PDF
		String ftlFile = "jgys/gcjgysjdtzs.xml";
		String fileName = DownloadUtils.exportPDF(data, ftlFile);
		
		//转换文件对象类型
        FileItem fileItem = createFileItem(fileName + ".pdf");
        MultipartFile mfile = new CommonsMultipartFile(fileItem);
        
        //测试代码,保存本地
//        copyFile(fileName + ".pdf","D:\\Download\\"+fileName+".pdf");
        
        //上传文件
        String attId = docUtil.createAtt(mfile, "CPT_ACCPTANCE_FILES_GCJGYSJDTZS", cptAcceptanceEntity.getId());
        
        result.put("fileName",fileName);
        result.put("attId",attId);
		return result;
	}

	@Override
	public void downloadGcjgysjdtzsFile(String cptId, HttpServletRequest request, HttpServletResponse response) {
		List<Attachment> attList = docUtil.getAttListByAttBusinessIdAndAttCode(cptId,"CPT_ACCPTANCE_FILES_GCJGYSJDTZS");
		if(null==attList || attList.size()<1) {
			throw new BusinessException("未找到工程竣工验收监督通知书");
		}
		String attId = null;
		for(int i=0; i<attList.size(); i++) {
			Attachment attachment = attList.get(i);
			attachment.getName();
			attId = attachment.getId();
		}
		
		
		InputStream is = docUtil.getFile(attId);
    	
		// 实现文件下载
       byte[] buffer = new byte[1024];
       BufferedInputStream bis = null;
       try {
           bis = new BufferedInputStream(is);
           OutputStream os = response.getOutputStream();
           int i = bis.read(buffer);
           while (i != -1) {
               os.write(buffer, 0, i);
               i = bis.read(buffer);
           }
       }
       catch (Exception e) {
           
       }
       finally {
           if (bis != null) {
               try {
                   bis.close();
               } catch (IOException e) {
                   e.printStackTrace();
               }
           }
           if (is != null) {
               try {
               	is.close();
               } catch (IOException e) {
                   e.printStackTrace();
               }
           }
       }
	}
	
	private void copyFile(String strOldpath,String strNewPath) {
		try {
			File fOldFile = new File(strOldpath);
			if (fOldFile.exists()) 
			{
				int bytesum = 0; 
				int byteread = 0;
				InputStream inputStream = new FileInputStream(fOldFile);
				FileOutputStream fileOutputStream = new FileOutputStream(strNewPath);
				byte[] buffer = new byte[1444]; 
				while ( (byteread = inputStream.read(buffer)) != -1) 
				{ 
					bytesum += byteread; //这一行是记录文件大小的，可以删去
					fileOutputStream.write(buffer, 0, byteread);//三个参数，第一个参数是写的内容，
					//第二个参数是从什么地方开始写，第三个参数是需要写的大小
				} 
				inputStream.close();
				fileOutputStream.close();
			}
		}catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			System.out.println("复制单个文件出错");
			e.printStackTrace();
		}
	}

	//获取FileItem对象：
	private FileItem createFileItem(String filePath) {
	    FileItemFactory factory = new DiskFileItemFactory(16, null);
	    String textFieldName = "textField";
	    int num = filePath.lastIndexOf(".");
	    String extFile = filePath.substring(num);
	    FileItem item = factory.createItem(textFieldName, "text/plain", true, "MyFileName");
	    File newfile = new File(filePath);
	    int bytesRead = 0;
	    byte[] buffer = new byte[8192];
	    try {
	        FileInputStream fis = new FileInputStream(newfile);
	        OutputStream os = item.getOutputStream();
	        while ((bytesRead = fis.read(buffer, 0, 8192)) != -1) {
	            os.write(buffer, 0, bytesRead);
	        }
	        os.close();
	        fis.close();
	    } catch (IOException e) {
	        e.printStackTrace();
	    }
	    return item;
	}

	@Override
	public void signGcjgysjdtzsFile(HttpServletRequest request, String cptId) {
		
		//查询并删除所有 工程竣工验收监督通知书
		List<Attachment> list = docUtil.getAttListByAttBusinessIdAndAttCode(cptId,"CPT_ACCPTANCE_FILES_GCJGYSJDTZS_SIGN");
		if(null!=list && list.size()>0) {
			for(int i=0; i<list.size(); i++) {
				Attachment attachment = list.get(i);
				docUtil.deleteAtts(Arrays.asList(attachment.getId().split(",")));
			}
		}
		
    	
        MultipartHttpServletRequest multipartRequest = WebUtils.getNativeRequest(request, MultipartHttpServletRequest.class);
        Map<String, MultipartFile> map = multipartRequest.getFileMap();
        MultipartFile attach = (MultipartFile) map.values().toArray()[0];
        InputStream inputStream = null;
        try {
            inputStream = attach.getInputStream();
        } catch (IOException e) {
            e.printStackTrace();
        }
        String attId2 = UUID.getId();
        docUtil.createAtt(attId2, null, null, "CPT_ACCPTANCE_FILES_GCJGYSJDTZS_SIGN", cptId, "工程竣工验收监督通知书.pdf", inputStream);
		
	}
	
	private void processMap(Map<String,Object> map) {
		//遍历map 
		for(Map.Entry<String, Object> entry : map.entrySet()) {
			//替换Null值, 防止生成doc文件时报错
            if(map.get(entry.getKey())==null) {
            	map.put(entry.getKey(), "");
            }
		}
	}
}
